
/**
\file
Definition of the sun::time class.
\author Sean Tromans
*/

#include <sun_pre_compiled.hpp>
#include <sun/time/time.hpp>

#if !defined(SUN_DISABLE_LUA)
#include <sun/lua/lua.hpp>
#endif

namespace sun
{

	/**
	Default constructor.
	\author Sean Tromans
	*/
	time::time( )
		:		m_milliseconds( 0 )
			,	m_seconds( 0.0f )
	{
	}

	/**
	Construct time from a milliseconds value.
	@param ms The time to become.
	\author Sean Tromans
	*/
	time::time( boost::int32_t ms )
	{
		milliseconds( ms );
	}

	/**
	Construct time from a seconds value.
	@param s The time to become.
	\author Sean Tromans
	*/
	time::time( float s )
	{
		seconds( s );
	}

	/**
	Sets the number of milliseconds in this time and recalculates the seconds value.
	@param ms The time to become.
	\author Sean Tromans
	*/
	void time::milliseconds( boost::int32_t ms )
	{
		m_milliseconds = ms;
		m_seconds = static_cast<float>( m_milliseconds ) / 1000.0f;
	}

	/**
	Sets the number of seconds in this time and recalculates the milliseconds value.
	@param s The time to become.
	\author Sean Tromans
	*/
	void time::seconds( float s )
	{
		m_seconds = s;
		m_milliseconds = static_cast<boost::int32_t>( m_seconds * 1000.0f );
	}

	/**
	Assigns a value to a time object from a millisecond value.
	@param ms The time to become.
	\author Sean Tromans
	*/
	time & time::operator = ( boost::int32_t ms )
	{
		milliseconds( ms );
		return *this;
	}

	/**
	Assigns a value to a time object from a second value.
	@param s The time to become.
	\author Sean Tromans
	*/
	time & time::operator = ( float s )
	{
		seconds( s );
		return *this;
	}

	/**
	Exposes the time class to the lua state.
	@param L The lua_State being initialised.
	\author Sean Tromans
	*/
	void time::lua_interface( lua_State * L )
	{
#if !defined(SUN_DISABLE_LUA)
		boost::int32_t	(time::*get_milliseconds)( ) const			= &time::milliseconds;
		void			(time::*set_milliseconds)( boost::int32_t )	= &time::milliseconds;

		float	(time::*get_seconds)( ) const	= &time::seconds;
		void	(time::*set_seconds)( float )	= &time::seconds;

		luabind::module( L, "sun" )
		[
			luabind::class_< time >( "time" )
				.def( luabind::constructor<>( ) )
				.def( luabind::constructor<float>( ) )
				.property( "milliseconds", get_milliseconds, set_milliseconds )
				.property( "seconds", get_seconds, set_seconds )
				.def( luabind::const_self == luabind::const_self )
		];
#else
		NMN_UNUSED( L );
#endif
	}

	/**
	Test for equality between two time objects.
	@param lhs The first time object to test.
	@param rhs The second time object to test.
	@return True if the two times are equal. (Uses the millisecond values to avoid floating point innaccuracies.)
	\author Sean Tromans
	*/
	bool operator == ( time const & lhs, time const & rhs )
	{
		return lhs.milliseconds( ) == rhs.milliseconds( );
	}

	/**
	Test for inequality between two time objects.
	@param lhs The first time object to test.
	@param rhs The second time object to test.
	@return True if the two times are not equal. (Uses the millisecond values to avoid floating point innaccuracies.)
	\author Sean Tromans
	*/
	bool operator != ( time const & lhs, time const & rhs )
	{
		return lhs.milliseconds( ) != rhs.milliseconds( );
	}

};
